package com.mybatistest.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mybatistest.entity.Result;
import com.mybatistest.entity.User;
import com.mybatistest.mapper.UserMapper;
import com.mybatistest.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

@Service
@Slf4j
@Validated
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Override
    public int insert(User user) {
        return userMapper.insert(user);
    }


    /**
     * 更新用户信息
     *
     * @param user 要更新的用户对象，必须符合特定的验证规则（由@Valid注解确保）
     * @return 总是返回true，表示更新操作已经尝试执行，如果更新失败，会抛出异常而不是返回false
     * <p>
     * 通过TransactionTemplate执行一个需要事务管理的更新操作，确保数据一致性和原子性
     * <p>
     * 如果用户更新失败，事务会被明确地标记为回滚，同时抛出IllegalArgumentException异常
     * <p>
     * 这个方法不直接返回更新操作的结果（布尔值），而是总是返回true，简化了调用方的处理逻辑
     * <p>
     * 调用方不需要处理返回的布尔值，但需要处理可能抛出的异常
     */
    @Override
    public boolean updateUser(@Valid User user) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                // 尝试更新用户信息，如果更新失败，事务将被设置为只回滚，并抛出异常
                boolean result = userMapper.updateUser(user);
                if (!result){
                    // 更新失败，设置事务为只回滚，并抛出异常
                    status.setRollbackOnly();
                    throw new IllegalArgumentException("更新失败");
                }
            }
        });
        // 表示更新操作已经尝试执行，返回true
        return true;
    }

    @Override
    public List<Result> queryByName(int age) {
        return userMapper.queryByName(age);
    }

    @Override
    public Integer totalCount(String name) {
        return userMapper.totalCount(name);
    }
}
